package svcauth

import (
	"context"

	"gitee.com/hexug/devcloud/mcenter/apps"
	"gitee.com/hexug/devcloud/mcenter/apps/service"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

type GrpcAuther struct {
	svc service.Server
}

// 构建函数
func NewGrpcAuther() *GrpcAuther {
	return &GrpcAuther{
		svc: apps.GetApp(service.AppName).(service.Server),
	}
}

// 认证中间件
func (g *GrpcAuther) GrpcAuth(
	ctx context.Context,
	req interface{},
	info *grpc.UnaryServerInfo,
	handler grpc.UnaryHandler) (
	resp interface{}, err error) {
	metaData, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return nil, status.Error(codes.Unauthenticated, "无法获取元数据")
	}
	clientId, clientSecret := g.GetInfoFromMetaData(metaData)
	if clientId == "" || clientSecret == "" {
		// fmt.Println(clientId, clientSecret)
		return nil, status.Error(codes.Unauthenticated, "未携带足够的key")
	}
	dsr := service.NewDetailServiceRequestByCREDENTAILID(clientId)
	svc, err := g.svc.DetailService(ctx, dsr)
	if err != nil {
		return nil, status.Errorf(codes.Unauthenticated, "%s", err.Error())
	}
	if svc.Credentail.ClientSecret != clientSecret {
		return nil, status.Error(codes.Unauthenticated, "认证不通过")
	}
	resp, err = handler(ctx, req)
	if err != nil {
		return nil, status.Errorf(codes.Unauthenticated, "%s", err.Error())
	}
	return resp, nil
}

// 从上下文中获取对应的元数据
func (g *GrpcAuther) GetInfoFromMetaData(md metadata.MD) (clientId, clientSecret string) {
	cids := md.Get(service.ClientHeaderKey)
	if len(cids) > 0 {
		clientId = cids[0]
	}
	sids := md.Get(service.ClientSecretKey)
	if len(sids) > 0 {
		clientSecret = sids[0]
	}
	return
}
